/**
 * 
 */
package edu.hitsz.cs.nlp.struct;

import java.io.FileWriter;
import java.io.IOException;
import java.util.Collection;
import java.util.Vector;

import edu.hitsz.cs.nlp.util.FeatureTemplate;

/**
 * @author tm
 *
 */
/**
 * CoNLL 2000 Shared task
 * @author lee
 * Confidence NN B-NP
 * in IN B-PP
 * the DT B-NP
 * pound NN I-NP
 * is VBZ B-VP
 * widely RB I-VP
 * expected VBN I-VP
 * to TO I-VP
 * take VB I-VP
 * another DT B-NP
 */

public class ConllSentence implements Cloneable{
	
	public int sentenceLength;
	//correct tags
	public Vector<String> senResultSignal;
	//predicted tags
	public Vector<Vector<String>> predictSignal;
	public Vector<Double> predictValue;
	//To store all the information
	public Vector<Vector<String>> word;

	
	public ConllSentence(){
		sentenceLength=0;
		senResultSignal=new Vector<String>();			
		predictSignal=new Vector<Vector<String>>();	
		Vector<String> newVec=new Vector<String>();
		predictSignal.add(newVec);
		predictValue=new Vector<Double>();
		word=new Vector<Vector<String>>();
	}
	
	/**
	 * read training data
	 * @param tempSentence A sentence structured as a vector of strings
	 * @param len the length of the vector
	 */
	public void processTrain(Vector<String> tempSentence,int len){
		sentenceLength=len;
		for(int i=0;i<sentenceLength;i++){
			String[] words=tempSentence.get(i).split("\t");
			int wordsSize=words.length;
			//read the whole sentence
			Vector<String> tmp=new Vector<String>();
			tmp.clear();
			int j=0;
			while(j<wordsSize)
				tmp.add(words[j++]);
			word.add(tmp);
			//read the result signal
			if(wordsSize>0){
				senResultSignal.add(words[wordsSize-1]);
				predictSignal.get(0).add(words[wordsSize-1]);
			}
		}
	}
	
	/**
	 * read testing data
	 * @param tempSentence A sentence structured as a vector of strings
	 * @param len the length of the vector
	 */
	public void processTest(Vector<String> tempSentence,int len){
		sentenceLength=len;
		for(int i=0;i<sentenceLength;i++){
			String[] words=tempSentence.get(i).split("\t");
			int wordsSize=words.length;
			Vector<String> tmp=new Vector<String>();
			int j=0;
			while(j<wordsSize)
				tmp.add(words[j++]);
			word.add(tmp);
		}
	}
	
	/**
	 * extract features from template file
	 * @param features Feature vector extracted from the sentence
	 * @param newTemplate Template class
	 * @param tokenNum The tokenNum of the sentence we want to extract
	 */
	public void extractTokenFeaturesFromTmpt(Vector<String> features, FeatureTemplate newTemplate,int tokenNum){
		int templateNum=newTemplate.template.size();
		//System.out.println("templateNum:"+Integer.toString(templateNum));
		//newTemplate.outputTemplate();
		for(int i=0;i<templateNum;i++){
			//System.out.println("j:"+Integer.toString(j));
			newTemplate.template.get(i);
			int singleTemplateNum=newTemplate.template.get(i).size();
			//System.out.println("singleTemplateNum:"+Integer.toString(singleTemplateNum));
			String templateString=Integer.toString(i+1)+":";			
			for(int j=0;j<singleTemplateNum;j++){
				//System.out.println("k:"+Integer.toString(k));
				int seq=newTemplate.template.get(i).get(j).row;
				if(seq+tokenNum<0||seq+tokenNum>=sentenceLength){
					templateString+="NULL+";
				}
				else{
					int position=newTemplate.template.get(i).get(j).column;
					if(position==-1||position>=word.get(0).size()){
						templateString+=predictSignal.get(0).get(seq+tokenNum)+"+";
					}
					else
						templateString+=word.get(seq+tokenNum).get(position)+"+";
					//int position=newTemplate.template.get(i).get(j).column;
					//templateString+=word.get(seq+tokenNum).get(position)+"+";				
				}				
			}
			int templateLength=templateString.length();
			templateString=templateString.substring(0,templateLength-1);
			//System.out.println("templateString:"+templateString);
			features.add(templateString);			
		}		
	}
	
	
	/**
	 * extract features from template file
	 * @param features Feature vector extracted from the sentence
	 * @param newTemplate Template class
	 * @param tokenNum The tokenNum of the sentence we want to extract
	 * @param kthBestNum the kth tags in predictSignal
	 */
	public void extractTokenFeaturesFromTmpt(Vector<String> features, FeatureTemplate newTemplate,int tokenNum, int kthBestNum){
		int templateNum=newTemplate.template.size();
		//System.out.println("templateNum:"+Integer.toString(templateNum));
		//newTemplate.outputTemplate();
		for(int i=0;i<templateNum;i++){
			//System.out.println("j:"+Integer.toString(j));
			newTemplate.template.get(i);
			int singleTemplateNum=newTemplate.template.get(i).size();
			//System.out.println("singleTemplateNum:"+Integer.toString(singleTemplateNum));
			String templateString=Integer.toString(i+1)+":";			
			for(int j=0;j<singleTemplateNum;j++){
				//System.out.println("k:"+Integer.toString(k));
				int seq=newTemplate.template.get(i).get(j).row;
				if(seq+tokenNum<0||seq+tokenNum>=sentenceLength){
					templateString+="NULL+";
				}
				else{
					int position=newTemplate.template.get(i).get(j).column;
					if(position==-1||position>=word.get(0).size()){
						templateString+=predictSignal.get(kthBestNum).get(seq+tokenNum)+"+";
					}
					else
						templateString+=word.get(seq+tokenNum).get(position)+"+";
					//int position=newTemplate.template.get(i).get(j).column;
					//templateString+=word.get(seq+tokenNum).get(position)+"+";				
				}				
			}
			int templateLength=templateString.length();
			templateString=templateString.substring(0,templateLength-1);
			//System.out.println("templateString:"+templateString);
			features.add(templateString);			
		}		
	}
	
	
	
	
	
	
	/**
	 * extract feature from paper (Collins, 2002; Spoustova, 2009) for POS tagging
	 * @param features Feature vector extracted from the sentence
	 * @param tokenNum The tokenNum of the sentence we want to extract
	 */
	public void extractTokenFeaturesPOS(Vector<String> features, int tokenNum){
		//determine the POS position in the vector word
		int feaSeq=1;
		
		/*
		//Previous tag
		String previousTag="";
		if(tokenNum<=0)
			previousTag="NULL";
		else
			previousTag=(String)predictSignal.get(0).get(tokenNum-1);
		features.add(Integer.toString(feaSeq++)+":"+previousTag);
		//Previous two tags
		String previousSecondTag="";
		if(tokenNum<=1)
			previousSecondTag="NULL";
		else
			previousSecondTag=(String)predictSignal.get(0).get(tokenNum-2);
		String previousTwoTags=previousSecondTag+"+"+previousTag;
		features.add(Integer.toString(feaSeq++)+":"+previousTwoTags);
		*/
		
		/*
		//First letter of the previous tag		
		String firstLetterOfPreviousTag=previousTag.substring(0, 1);
		features.add(Integer.toString(feaSeq++)+":"+firstLetterOfPreviousTag);
		*/
		//current word form
		String currentWord=(String)word.get(tokenNum).get(0);
		features.add(Integer.toString(feaSeq++)+":"+currentWord);
		//previous word form
		String previousWord="";
		if(tokenNum<=0)
			previousWord="NULL";
		else
			previousWord=(String)word.get(tokenNum-1).get(0);
		features.add(Integer.toString(feaSeq++)+":"+previousWord);
		//previous two word forms
		String previousSecondWord="";
		if(tokenNum<=1)
			previousSecondWord="NULL";
		else
			previousSecondWord=(String)word.get(tokenNum-2).get(0);
		features.add(Integer.toString(feaSeq++)+":"+previousSecondWord);
		//String previousTwoWordForms=previousSecondWord+"+"+previousWord;
		//features.add(Integer.toString(feaSeq++)+":"+previousTwoWordForms);
		
		//Following word form
		String followingWord="";
		if(tokenNum+1>=sentenceLength)
			followingWord="NULL";
		else
			followingWord=(String)word.get(tokenNum+1).get(0);
		features.add(Integer.toString(feaSeq++)+":"+followingWord);
		//Following two word forms
		String followingSecondWord="";
		if(tokenNum+2>=sentenceLength)
			followingSecondWord="NULL";
		else
			followingSecondWord=(String)word.get(tokenNum+2).get(0);
		features.add(Integer.toString(feaSeq++)+":"+followingSecondWord);
		//String followingTwoWords=followingWord+"+"+followingSecondWord;
		//features.add(Integer.toString(feaSeq++)+":"+followingTwoWords);		
		/*
		//Last but one word form		
		String lastButOneWord="";
		if(sentenceLength==1)
			lastButOneWord="NULL";
		else
			lastButOneWord=(String)word.get(sentenceLength-2).get(0);
		features.add(Integer.toString(feaSeq++)+":"+lastButOneWord);
		*/
		//prefixes of length 1-9
		int prefixNumber=4;
		int currentWordLength=currentWord.length();
		for(int j=0;j<prefixNumber;j++){
			String prefixWord="";
			if(currentWordLength>j)
				prefixWord=currentWord.substring(0,j+1);
			else
				prefixWord=currentWord;
			features.add(Integer.toString(feaSeq++)+":"+prefixWord);
		}
				
		//suffixes of length 1-9
		int suffixNumber=4;
		currentWordLength=currentWord.length();
		for(int j=0;j<suffixNumber;j++){
			String suffixWord="";
			if(currentWordLength>j)
				suffixWord=currentWord.substring(currentWordLength-1-j);
			else
				suffixWord=currentWord;
			features.add(Integer.toString(feaSeq++)+":"+suffixWord);
		}
		//Contains number
		boolean containNumber=false;
		for(int j=0;j<currentWordLength;j++){
			if(Character.isDigit(currentWord.charAt(j))){
				containNumber=true;
				break;
			}		
		}
		features.add(Integer.toString(feaSeq++)+":"+containNumber);
		//contains dash(hyphen)
		boolean containDash=false;
		for(int j=0;j<currentWordLength;j++){
			if(currentWord.charAt(j)=='-'){
				containDash=true;
				break;
			}		
		}
		features.add(Integer.toString(feaSeq++)+":"+containDash);
		//contains upper case letter
		boolean containUpper=false;
		for(int j=0;j<currentWordLength;j++){
			if(Character.isUpperCase(currentWord.charAt(j))){
				containUpper=true;
				break;
			}		
		}
		features.add(Integer.toString(feaSeq++)+":"+containUpper);				
	}
	
	
	/**
	 * extract features for Chunking
	 * @param features Feature vector extracted from the sentence
	 * @param tokenNum The tokenNum of the sentence we want to extract
	*/
	public void extractTokenFeaturesChunk(Vector<String> features, int tokenNum){		
		//determine the POS position in the vector word
		int feaSeq=1;
		
		//current word form
		String currentWord=(String)word.get(tokenNum).get(0);
		features.add(Integer.toString(feaSeq++)+":"+currentWord);
		//previous word form
		String previousWord="";
		if(tokenNum<=0)
			previousWord="NULL";
		else
			previousWord=(String)word.get(tokenNum-1).get(0);
		features.add(Integer.toString(feaSeq++)+":"+previousWord);
		//previous two word forms
		String previousSecondWord="";
		if(tokenNum<=1)
			previousSecondWord="NULL";
		else
			previousSecondWord=(String)word.get(tokenNum-2).get(0);
		features.add(Integer.toString(feaSeq++)+":"+previousSecondWord);
		//Following word form
		String followingWord="";
		if(tokenNum+1>=sentenceLength)
			followingWord="NULL";
		else
			followingWord=(String)word.get(tokenNum+1).get(0);
		features.add(Integer.toString(feaSeq++)+":"+followingWord);
		//Following two word forms
		String followingSecondWord="";
		if(tokenNum+2>=sentenceLength)
			followingSecondWord="NULL";
		else
			followingSecondWord=(String)word.get(tokenNum+2).get(0);
		features.add(Integer.toString(feaSeq++)+":"+followingSecondWord);
		
		//two word feature combination		
		String previousTwoWords=previousSecondWord+"+"+previousWord;
		features.add(Integer.toString(feaSeq++)+":"+previousTwoWords);
		String preciousCurrentWords=previousWord+"+"+currentWord;
		features.add(Integer.toString(feaSeq++)+":"+preciousCurrentWords);
		String currentFollowingWords=currentWord+"+"+followingWord;
		features.add(Integer.toString(feaSeq++)+":"+currentFollowingWords);			
		String followingTwoWords=followingWord+"+"+followingSecondWord;
		features.add(Integer.toString(feaSeq++)+":"+followingTwoWords);		
		
		//three word combination
		features.add(Integer.toString(feaSeq++)+":"+previousTwoWords+"+"+currentWord);
		features.add(Integer.toString(feaSeq++)+":"+preciousCurrentWords+"+"+followingWord);
		features.add(Integer.toString(feaSeq++)+":"+currentWord+"+"+followingTwoWords);
		
		
		/*
		//Last but one word form		
		String lastButOneWord="";
		if(sentenceLength==1)
			lastButOneWord="NULL";
		else
			lastButOneWord=(String)word.get(sentenceLength-2).get(0);
		features.add(Integer.toString(feaSeq++)+":"+lastButOneWord);
		*/
		//prefixes of length 1-9
		int prefixNumber=4;
		int currentWordLength=currentWord.length();
		for(int j=0;j<prefixNumber;j++){
			String prefixWord="";
			if(currentWordLength>j)
				prefixWord=currentWord.substring(0,j+1);
			else
				prefixWord=currentWord;
			features.add(Integer.toString(feaSeq++)+":"+prefixWord);
		}
				
		//suffixes of length 1-9
		int suffixNumber=4;
		currentWordLength=currentWord.length();
		for(int j=0;j<suffixNumber;j++){
			String suffixWord="";
			if(currentWordLength>j)
				suffixWord=currentWord.substring(currentWordLength-1-j);
			else
				suffixWord=currentWord;
			features.add(Integer.toString(feaSeq++)+":"+suffixWord);
		}
		//Contains number
		boolean containNumber=false;
		for(int j=0;j<currentWordLength;j++){
			if(Character.isDigit(currentWord.charAt(j))){
				containNumber=true;
				break;
			}		
		}
		features.add(Integer.toString(feaSeq++)+":"+containNumber);
		//contains dash(hyphen)
		boolean containDash=false;
		for(int j=0;j<currentWordLength;j++){
			if(currentWord.charAt(j)=='-'){
				containDash=true;
				break;
			}		
		}
		features.add(Integer.toString(feaSeq++)+":"+containDash);
		//contains upper case letter
		boolean containUpper=false;
		for(int j=0;j<currentWordLength;j++){
			if(Character.isUpperCase(currentWord.charAt(j))){
				containUpper=true;
				break;
			}		
		}
		features.add(Integer.toString(feaSeq++)+":"+containUpper);	
	
	}
	
	
	
	
	/**
	 * extract feature POS tagging from word and chunk features
	 * @param features Feature vector extracted from the sentence
	 * @param tokenNum The tokenNum of the sentence we want to extract
	 */
	public void extractTokenFeaturesChunkPOS(Vector<String> features, int tokenNum){
		//determine the POS position in the vector word
		int feaSeq=1;
		/*
		//Previous tag
		String previousTag="";
		if(tokenNum<=0)
			previousTag="NULL";
		else
			previousTag=(String)predictSignal.get(0).get(tokenNum-1);
		features.add(Integer.toString(feaSeq++)+":"+previousTag);
		//Previous two tags
		String previousSecondTag="";
		if(tokenNum<=1)
			previousSecondTag="NULL";
		else
			previousSecondTag=(String)predictSignal.get(0).get(tokenNum-2);
		String previousTwoTags=previousSecondTag+"+"+previousTag;
		features.add(Integer.toString(feaSeq++)+":"+previousTwoTags);
		//First letter of the previous tag*
		String firstLetterOfPreviousTag=previousTag.substring(0, 1);
		features.add(Integer.toString(feaSeq++)+":"+firstLetterOfPreviousTag);
		*/
		
		//current word form
		String currentWord=(String)word.get(tokenNum).get(0);
		features.add(Integer.toString(feaSeq++)+":"+currentWord);
		//previous word form
		String previousWord="";
		if(tokenNum<=0)
			previousWord="NULL";
		else
			previousWord=(String)word.get(tokenNum-1).get(0);
		features.add(Integer.toString(feaSeq++)+":"+previousWord);
		//previous two word forms
		String previousSecondWord="";
		if(tokenNum<=1)
			previousSecondWord="NULL";
		else
			previousSecondWord=(String)word.get(tokenNum-2).get(0);
		features.add(Integer.toString(feaSeq++)+":"+previousSecondWord);
		//String previousTwoWordForms=previousSecondWord+"+"+previousWord;
		//features.add(Integer.toString(feaSeq++)+":"+previousTwoWordForms);
		
		//Following word form
		String followingWord="";
		if(tokenNum+1>=sentenceLength)
			followingWord="NULL";
		else
			followingWord=(String)word.get(tokenNum+1).get(0);
		features.add(Integer.toString(feaSeq++)+":"+followingWord);
		//Following two word forms
		String followingSecondWord="";
		if(tokenNum+2>=sentenceLength)
			followingSecondWord="NULL";
		else
			followingSecondWord=(String)word.get(tokenNum+2).get(0);
		features.add(Integer.toString(feaSeq++)+":"+followingSecondWord);
		//String followingTwoWords=followingWord+"+"+followingSecondWord;
		//features.add(Integer.toString(feaSeq++)+":"+followingTwoWords);		
		/*
		//Last but one word form		
		String lastButOneWord="";
		if(sentenceLength==1)
			lastButOneWord="NULL";
		else
			lastButOneWord=(String)word.get(sentenceLength-2).get(0);
		features.add(Integer.toString(feaSeq++)+":"+lastButOneWord);
		*/
		//prefixes of length 1-9
		int prefixNumber=4;
		int currentWordLength=currentWord.length();
		for(int j=0;j<prefixNumber;j++){
			String prefixWord="";
			if(currentWordLength>j)
				prefixWord=currentWord.substring(0,j+1);
			else
				prefixWord=currentWord;
			features.add(Integer.toString(feaSeq++)+":"+prefixWord);
		}
				
		//suffixes of length 1-9
		int suffixNumber=4;
		currentWordLength=currentWord.length();
		for(int j=0;j<suffixNumber;j++){
			String suffixWord="";
			if(currentWordLength>j)
				suffixWord=currentWord.substring(currentWordLength-1-j);
			else
				suffixWord=currentWord;
			features.add(Integer.toString(feaSeq++)+":"+suffixWord);
		}
		//Contains number
		boolean containNumber=false;
		for(int j=0;j<currentWordLength;j++){
			if(Character.isDigit(currentWord.charAt(j))){
				containNumber=true;
				break;
			}		
		}
		features.add(Integer.toString(feaSeq++)+":"+containNumber);
		//contains dash(hyphen)
		boolean containDash=false;
		for(int j=0;j<currentWordLength;j++){
			if(currentWord.charAt(j)=='-'){
				containDash=true;
				break;
			}		
		}
		features.add(Integer.toString(feaSeq++)+":"+containDash);
		//contains upper case letter
		boolean containUpper=false;
		for(int j=0;j<currentWordLength;j++){
			if(Character.isUpperCase(currentWord.charAt(j))){
				containUpper=true;
				break;
			}		
		}
		features.add(Integer.toString(feaSeq++)+":"+containUpper);		
		
		//current Chunk form
		String currentChunk=(String)word.get(tokenNum).get(1);
		features.add(Integer.toString(feaSeq++)+":"+currentChunk);
		//previous Chunk form
		String previousChunk="";
		if(tokenNum<=0)
			previousChunk="NULL";
		else
			previousChunk=(String)word.get(tokenNum-1).get(1);
		features.add(Integer.toString(feaSeq++)+":"+previousChunk);
		//Following Chunk form
		String followingChunk="";
		if(tokenNum+1>=sentenceLength)
			followingChunk="NULL";
		else
			followingChunk=(String)word.get(tokenNum+1).get(1);
		features.add(Integer.toString(feaSeq++)+":"+followingChunk);
		
		String previousCurrentChunk=previousChunk+"+"+currentChunk;
		features.add(Integer.toString(feaSeq++)+":"+previousCurrentChunk);
		String currentFollowingChunk=currentChunk+"+"+followingChunk;
		features.add(Integer.toString(feaSeq++)+":"+currentFollowingChunk);
		
	}
	
	
	
	
	/**
	 * extract feature from paper (Spoustova, 2009) for POS tagging
	 */
	public void extractFeaturesPOS(Vector<String> features){
		for(int i=0;i<sentenceLength;i++){
			extractTokenFeaturesPOS(features, i);
		}
	}
		
	public void extractAndStoreFeatures (FileWriter newFile, FeatureTemplate newTemplate) throws IOException{
		Vector<String> newVector=new Vector<String>();
		int senLen=this.sentenceLength;
		String tmpString="";
		for(int i=0;i<senLen;i++){
			newVector.clear();
			this.extractTokenFeaturesFromTmpt(newVector, newTemplate, i);
			String newString="";
			for(String tmp : newVector){
				newString+="\t"+tmp;
			}
			int num=this.word.get(i).size();			
			tmpString+=newString.trim()+"\t"+this.predictSignal.get(0).get(i)+"\n";
			//tmpString+=this.word.get(i).get(num-2)+" "+this.predictSignal.get(0).get(i)+" ---- "+newString.trim()+"\n";
		}
		newFile.write(tmpString+"\n");		
	}
	
	
	public void extractAndStoreFeatures (FileWriter newFile, String type) throws IOException{
		Vector<String> newVector=new Vector<String>();
		int senLen=this.sentenceLength;
		String tmpString="";
		for(int i=0;i<senLen;i++){
			newVector.clear();
			if(type.equals("pos"))
				this.extractTokenFeaturesPOS(newVector, i);
			else if(type.equals("chunk"))
				this.extractTokenFeaturesChunk(newVector, i);
			else if(type.equals("chunkpos"))
				this.extractTokenFeaturesChunkPOS(newVector, i);
			else{
				System.out.println("The input type is not found. Please check");
				System.exit(1);
			}
			String newString="";
			for(String tmp : newVector){
				newString+="\t"+tmp;
			}
			int num=this.word.get(i).size();			
			tmpString+=newString.trim()+"\t"+this.predictSignal.get(0).get(i)+"\n";
			//tmpString+=this.word.get(i).get(num-2)+" "+this.predictSignal.get(0).get(i)+" ---- "+newString.trim()+"\n";
		}
		newFile.write(tmpString+"\n");		
	}
	
	
	
	/**
	 * The limiting conditions to choose the next tag for sentence in BIO representation
	 * @param preTokens
	 * @param curToken
	 * @return
	 */
	public boolean satisfyConsBIO(Vector<String> preTokens,String curToken){
		if(curToken.equals("O"))
				return true;
		else{
			String[] curTag=curToken.split("_");
			if(curTag[0].equals("B"))
					return true;
			else{
				if(preTokens.size()==0)
					return false;
				String[] preTag=preTokens.get(preTokens.size()-1).split("_");
				if(preTag[0].equals("I")||preTag[0].equals("O"))
					return false;
				else{
					if(preTag[1].equals(curTag[1]))
						return true;
					else
						return false;
				}
			}
			
		}
			
	}
	
	
	/**
	 *  
	 */
	public void outputSentence(){		
		if(sentenceLength>0){
			int componentLen=word.get(0).size();
			for(int i=0; i<sentenceLength; i++){
				String tmpString="";
				for(int j=0;j<componentLen;j++)
					tmpString+=word.get(i).get(j)+"\t";
				System.out.println(tmpString.trim());
			}
		}
	}
	

	
	/**
	 * Store sentence in file
	 * @throws IOException 
	 * 
	 */
	public void storeSentence(FileWriter newWriter) throws IOException{
		int i=0;
		if(this.sentenceLength>0){
			int componentLen=word.get(0).size();
			for(;i<this.sentenceLength;i++){
				String tmpString="";
				for(int j=0;j<componentLen;j++)
					tmpString+="\t"+word.get(i).get(j);
				newWriter.write(tmpString.trim()+"\n");
			}
		}
		newWriter.write("\n");
	}
	
	/**
	 * Store sentence in which the tokens are in reverse order. 
	 * @throws IOException 
	 * 
	 */
	public void storeReverseSentence(FileWriter newWriter) throws IOException{
		int i=sentenceLength-1;
		if(sentenceLength>0){
			int componentLen=word.get(0).size();
			for(;i>=0;i--){
				String tmpString="";
				for(int j=0;j<componentLen;j++)
					tmpString+="\t"+word.get(i).get(j);
				newWriter.write(tmpString.trim()+"\n");
			}
		}
		newWriter.write("\n");
	}
	
	
	
	/**
	 * Store
	 * @param newWriter
	 * @throws IOException
	 */
	public void storeSenResultSentence(FileWriter newWriter) throws IOException{
		for(int i=0;i<sentenceLength;i++){
			newWriter.write(senResultSignal.get(i)+"\n");
		}
		newWriter.write("\n");
	}
	
	
	
	/**
	 * Store
	 * @param newWriter
	 * @throws IOException
	 */
	public void storePredictSentence(FileWriter newWriter) throws IOException{
		for(int i=0;i<sentenceLength;i++){
			newWriter.write(predictSignal.get(0).get(i)+"\n");
		}
		newWriter.write("\n");
	}
	
	
	public void storePredictSentence(FileWriter newWriter, int ith) throws IOException{
		for(int i=0;i<sentenceLength;i++){
			newWriter.write(predictSignal.get(ith).get(i)+"\n");
		}
		newWriter.write("\n");
	}
	
	 
	public void printFeatures(Vector<String> features){
		System.out.println();
		int len=features.size();
		for(int i=0;i<len;i++){
			System.out.println(features.get(i));
		}
	}
	
	
	public Object clone(){
		ConllSentence o=null;
		try{
			o = (ConllSentence)super.clone();
			}
		catch(CloneNotSupportedException e){
			e.printStackTrace();
			}
		return o;
	}
		
	
	static void test(){
		ConllSentence newSen=new ConllSentence();
		Vector<String> newVec=new Vector<String>();
		//newVec.add("B");
		System.out.println(newSen.satisfyConsBIO(newVec,"O"));
	}
	
	
	public static void main(String[] args){
		test();
	}
	
} 

	    
